package com.chenyaowei.happyhub.config;

import com.chenyaowei.happyhub.security.JwtAuthenticationTokenFilter;
import com.chenyaowei.happyhub.security.WxAppletAuthenticationFilter;
import com.chenyaowei.happyhub.security.WxAppletAuthenticationManager;
import com.chenyaowei.happyhub.security.handler.CustomAccessDeniedHandler;
import com.chenyaowei.happyhub.security.handler.CustomAuthenticationEntryPoint;
import com.chenyaowei.happyhub.security.handler.CustomAuthenticationSuccessHandler;
import com.chenyaowei.happyhub.service.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.annotation.Resource;

@Configuration
@Order(99)
public class WeChatLoginSecurityConfig extends WebSecurityConfigurerAdapter {
    @Resource
    UserDetailsServiceImpl userDetailsService;
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        /*auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                .withUser("root")
                .password(new BCryptPasswordEncoder().encode("root"))
                .roles("USER");*/

        auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
    }
    @Override
    public void configure(WebSecurity web) {
        web.ignoring().antMatchers("/assets/**","/favicon.ico", "/error","/image/**","/icons/**","/nav_img/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf()
                .disable()
                .sessionManagement()
                // 不创建Session, 使用jwt来管理用户的登录状态
                //.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                // /error 异常端点不需要用户认证
                .antMatchers("/error/**","/admin/login/tofindpassword","/admin/login/findpassword").permitAll()
                // 其余的全部需要用户认证
                .antMatchers("/wechat/**").hasRole("USER")
                .antMatchers("/admin/**").access("hasAnyRole('ADMIN','ROOT')")
                .antMatchers("/adminManger/**").hasRole("ADMIN")
                .and()
                .formLogin().loginPage("/admin/login").permitAll().defaultSuccessUrl("/admin/good").and()
                .logout()
                .logoutUrl("/admin/logout").permitAll().logoutSuccessUrl("/admin/login").and();
                /*.exceptionHandling()
                .authenticationEntryPoint(new CustomAuthenticationEntryPoint())
                .accessDeniedHandler(new CustomAccessDeniedHandler());*/
        // 使用WxAppletAuthenticationFilter替换默认的认证过滤器UsernamePasswordAuthenticationFilter
        http.addFilterBefore(wxAppletAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
                // 在WxAppletAuthenticationFilter前面添加用于验证jwt，识别用户是否登录的过滤器
                .addFilterBefore(jwtAuthenticationTokenFilter(), WxAppletAuthenticationFilter.class);
    }

    @Autowired
    private WxAppletAuthenticationManager wxAppletAuthenticationManager;

    @Bean
    public WxAppletAuthenticationFilter wxAppletAuthenticationFilter(){
        WxAppletAuthenticationFilter wxAppletAuthenticationFilter = new WxAppletAuthenticationFilter("/wechat/login");
        wxAppletAuthenticationFilter.setAuthenticationManager(wxAppletAuthenticationManager);
        wxAppletAuthenticationFilter.setAuthenticationSuccessHandler(customAuthenticationSuccessHandler());
        return wxAppletAuthenticationFilter;
    }
    @Bean
    public CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler(){
        return new CustomAuthenticationSuccessHandler();
    }
    @Bean
    public JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter() {
        return new JwtAuthenticationTokenFilter();
    }
}
